/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.security.comment.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.event.LevelUpEvent;
import com.yami.shop.bean.event.UserRegisterLogEvent;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.UserRegisterExcelParam;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.dao.UserExtensionMapper;
import com.yami.shop.dao.UserMapper;
import com.yami.shop.security.comment.dao.AppConnectMapper;
import com.yami.shop.security.comment.enums.App;
import com.yami.shop.security.comment.model.AppConnect;
import com.yami.shop.security.comment.service.AppConnectService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.service.UserService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 *
 * @author lgh on 2018/09/07.
 */
@Service
@AllArgsConstructor
public class AppConnectServiceImpl extends ServiceImpl<AppConnectMapper, AppConnect> implements AppConnectService {

	private final AppConnectMapper appConnectMapper;
	private final ApplicationContext applicationContext;

	private final UserMapper userMapper;
	private final UserService userService;
	private final UserExtensionMapper userExtensionMapper;
	private final UserExtensionService userExtensionService;
	private final PasswordEncoder passwordEncoder;
	private final MapperFacade mapperFacade;

	/**
	 * YamiUserServiceImpl#insertUserIfNecessary 将会清除该缓存信息
	 * @param bizUserId
	 * @return
	 */
	@Override
	public AppConnect getByBizUserId(String bizUserId, Integer appId) {
		return appConnectMapper.getByBizUserId(bizUserId, appId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public User registerOrBindUser(User user, AppConnect appConnect, Integer appId) {
		if (StrUtil.isBlank(user.getUserId())) {
			if (userMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getUserName, user.getUserName())) > 0) {
				// 用户名已存在
				throw new YamiShopBindException("yami.user.account.exist");
			}
			String userId = IdUtil.simpleUUID();
			user.setUserId(userId);
			user.setLevel(1);
			user.setLevelType(0);
			userMapper.insert(user);
			UserExtension userExtension = new UserExtension();
			userExtension.setBalance(0.0);
			userExtension.setTotalBalance(0.0);
			userExtension.setGrowth(0);
			userExtension.setLevel(1);
			userExtension.setLevelType(0);
			userExtension.setScore(0);
			userExtension.setUpdateTime(new Date());
			userExtension.setVersion(0);
			userExtension.setUserId(userId);
			userExtensionMapper.insert(userExtension);
			//用户注册成功后发送等级提升事件
			applicationContext.publishEvent(new LevelUpEvent(userExtension,1,0));
		} else {
			if (appConnect != null&& StrUtil.isBlank(user.getPic())) {
				User userParam = new User();
				userParam.setUserId(user.getUserId());
				userParam.setModifyTime(new Date());
				userParam.setPic(appConnect.getImageUrl());
				userService.updateById(userParam);
			}
		}
		if (appConnect == null) {
			// 避免重复插入数据
			if (appConnectMapper.getByBizUserId(user.getUserId(), appId) != null) {
				return user;
			}
			appConnect = new AppConnect();
			appConnect.setUserId(user.getUserId());
			appConnect.setNickName(user.getNickName());
			appConnect.setImageUrl(user.getPic());

			// 0表示是系统的用户，不是第三方的
			appConnect.setAppId(appId);
			appConnectMapper.insert(appConnect);
		} else if (StrUtil.isBlank(appConnect.getUserId()) || Objects.isNull(appId)) {
			appConnect.setAppId(appId);
			appConnect.setUserId(user.getUserId());
			appConnectMapper.updateByBizUserIdAndAppId(appConnect);
		}

		return user;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Integer batchRegisterUser(List<UserRegisterExcelParam> userList) {
		// 成功注册用户条数
		int registerNum = 0;
		if (CollectionUtils.isEmpty(userList)) {
			return registerNum;
		}
		List<String> phones = userList.stream().map(UserRegisterExcelParam::getPhone).collect(Collectors.toList());
		List<String> mails = userList.stream().map(UserRegisterExcelParam::getUserMail).collect(Collectors.toList());
		// 查询已经存在的手机号用户
		List<User> users = userMapper.listByUserPhones(phones);
		// 查询已经存在的邮箱用户
		List<User> userListByMail =userMapper.listByUserMails(mails);
		if (CollectionUtils.isNotEmpty(users)) {
			List<String> mobiles = users.stream().map(User::getUserMobile).collect(Collectors.toList());
			userList = userList.stream().filter(item -> !mobiles.contains(item.getPhone())).collect(Collectors.toList());
		}
		if (CollectionUtils.isNotEmpty(userListByMail) && CollectionUtils.isNotEmpty(userList)) {
			List<String> userMails = userListByMail.stream().map(User::getUserMail).collect(Collectors.toList());
			userList = userList.stream().filter(item -> !userMails.contains(item.getUserMail())).collect(Collectors.toList());
		}
		if (CollectionUtils.isEmpty(userList)) {
			return registerNum;
		}
		registerNum = userList.size();
		Date now = new Date();
		// 用户
		List<User> userSave = new ArrayList<>();
		// 用户扩展表
		List<UserExtension> userExtensionsSave = new ArrayList<>();
		// 第三方表
		List<AppConnect> appConnectList = new ArrayList<>();
		for (UserRegisterExcelParam param : userList) {
			// 用户
			String userId = IdUtil.simpleUUID();
			User user = mapperFacade.map(param, User.class);
			user.setUserId(userId);
			user.setUserMobile(param.getPhone());
			user.setLoginPassword(passwordEncoder.encode(param.getPassword()));
			user.setUserName(param.getNickName());
			user.setModifyTime(now);
			user.setUserRegtime(now);
			user.setStatus(1);
			userSave.add(user);
			// 用户扩展信息
			UserExtension userExtension = new UserExtension();
			userExtension.setUserId(userId);
			userExtension.setLevel(user.getLevel());
			userExtension.setLevelType(user.getLevelType());
			userExtension.setGrowth(param.getGrowth());
			userExtension.setScore(param.getScore());
			userExtension.setBalance(param.getBalance());
			userExtension.setTotalBalance(param.getBalance());
			userExtension.setVersion(0);
			userExtension.setUpdateTime(now);
			userExtensionsSave.add(userExtension);
			// tz_app_connect // 除了小程序和公众号
			List<Integer> appTypes = App.listAppType();
			appTypes.remove(App.MINI.value());
			appTypes.remove(App.MP.value());
			for (Integer appType : appTypes) {
				AppConnect appConnect = new AppConnect();
				appConnect.setUserId(userId);
				appConnect.setAppId(appType);
				appConnect.setNickName(user.getNickName());
				appConnectList.add(appConnect);
			}
		}
		// 用户id都是新生成的userId,不用处理userId重复数据
		this.saveBatch(appConnectList);
		userService.saveBatch(userSave);
		userExtensionService.saveBatch(userExtensionsSave);
		//用户注册成功后发送日志事件 积分log 成长值log
		applicationContext.publishEvent(new UserRegisterLogEvent(userExtensionsSave));
		return registerNum;
	}

}
